package com.qianfeng.openplatform.zuul.filter;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.qianfeng.openplatform.common.BaseResultBean;
import com.qianfeng.openplatform.common.CommonsConstants;
import com.qianfeng.openplatform.common.SystemParams;
import com.qianfeng.openplatform.zuul.feign.CacheFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Enumeration;
import java.util.Map;

/**
 * @Author LJF
 * @Date 2020/8/5 19:07
 * @Version 1.0
 */
@Component
public class RoutingFilter extends ZuulFilter {

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private CacheFeign cacheFeign;

    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return 88;
    }

    @Override
    public boolean shouldFilter() {
        return RequestContext.getCurrentContext().sendZuulResponse();
    }

    @Override
    public Object run() throws ZuulException {
        //获取RequestContext对象
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        //获取用户携带的标识，我们约定的标识是method
        String method = request.getParameter("method");
        try {
            Map<Object, Object> apiMappingInfo = cacheFeign.hGetAll(SystemParams.METHOD_REDIS_PRE+method);
            if (apiMappingInfo!=null && apiMappingInfo.size()>0){
                //获取路由到serviceId服务的url服务上
                Object serviceId = apiMappingInfo.get("serviceId");
                String insideApiUrl = (String) apiMappingInfo.get("insideApiUrl");

                Enumeration<String> parameterNames = request.getParameterNames();
                while (parameterNames.hasMoreElements()){
                    String param = parameterNames.nextElement();
                    insideApiUrl = insideApiUrl.replace(
                            "{"+param+"}", request.getParameter(param));
                }

                //动态路由到serviceId服务的url地址上
                currentContext.put(FilterConstants.SERVICE_ID_KEY,serviceId);
                currentContext.put(FilterConstants.REQUEST_URI_KEY,insideApiUrl);

                return null;
            }
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        //路由失败，拦截请求，返回信息
        currentContext.setSendZuulResponse(false);
        HttpServletResponse response = currentContext.getResponse();
//        response.setContentType("text/html;charset=utf-8");
//        currentContext.setResponseBody("路由失败，检查参数！！");
        BaseResultBean resultBean = new BaseResultBean();
        resultBean.setCode(CommonsConstants.ROUTING_ERROR);
        resultBean.setMsg("与"+method+"相关的服务没有找到，请确认后再重试");
        response.setContentType("application/json;charset=utf-8");
        try {
            currentContext.setResponseBody(objectMapper.writeValueAsString(resultBean));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}
